<template>
  <div class="card-list-demo">
    <h2>卡片列表动画</h2>

    <div class="filter-controls">
      <button
        v-for="category in categories"
        :key="category"
        @click="currentFilter = category"
        :class="{ active: currentFilter === category }"
      >
        {{ category }}
      </button>
    </div>

    <TransitionGroup
      name="card"
      tag="div"
      class="card-grid"
      @before-enter="onBeforeEnter"
      @enter="onEnter"
    >
      <div
        v-for="(card, index) in filteredCards"
        :key="card.id"
        :data-index="index"
        class="card"
        :style="{ background: card.color }"
      >
        <h3>{{ card.title }}</h3>
        <p>{{ card.description }}</p>
        <span class="category">{{ card.category }}</span>
      </div>
    </TransitionGroup>
  </div>
</template>
<script setup>
import { ref, computed } from 'vue'

const currentFilter = ref('全部')

const cards = ref([
  {
    id: 1,
    title: 'Vue3 基础',
    description: '学习 Vue3 的核心概念和基础语法',
    category: '学习',
    color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
  },
  {
    id: 2,
    title: '项目部署',
    description: '将 Vue 应用部署到生产环境',
    category: '工作',
    color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
  },
  {
    id: 3,
    title: '技术分享',
    description: '准备下周的技术分享会议',
    category: '工作',
    color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
  },
  {
    id: 4,
    title: '响应式设计',
    description: '深入理解 Vue3 的响应式原理',
    category: '学习',
    color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
  },
  {
    id: 5,
    title: '户外运动',
    description: '周末去爬山，享受自然风光',
    category: '生活',
    color: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
  },
  {
    id: 6,
    title: '读书笔记',
    description: '整理最近阅读的技术书籍笔记',
    category: '学习',
    color: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
  },
])

const categories = ref(['全部', '学习', '工作', '生活'])

const filteredCards = computed(() => {
  if (currentFilter.value === '全部') {
    return cards.value
  }
  return cards.value.filter((card) => card.category === currentFilter.value)
})

// 交错动画
const onBeforeEnter = (el) => {
  el.style.opacity = 0
  el.style.transform = 'translateY(30px)'
}

const onEnter = (el, done) => {
  const delay = el.dataset.index * 100
  setTimeout(() => {
    el.style.transition = 'all 0.4s ease'
    el.style.opacity = 1
    el.style.transform = 'translateY(0)'
    done()
  }, delay)
}
</script>
<style scoped>
.card-list-demo {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.filter-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 30px;
  justify-content: center;
  flex-wrap: wrap;
}

.filter-controls button {
  padding: 8px 16px;
  background: #ecf0f1;
  color: #2c3e50;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.filter-controls button.active,
.filter-controls button:hover {
  background: #3498db;
  color: white;
  transform: translateY(-2px);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
}

.card {
  padding: 20px;
  border-radius: 12px;
  color: white;
  cursor: pointer;
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.card h3 {
  margin: 0 0 10px 0;
  font-size: 1.2em;
}

.card p {
  margin: 0 0 15px 0;
  opacity: 0.9;
  line-height: 1.5;
}

.category {
  background: rgba(255, 255, 255, 0.2);
  padding: 4px 12px;
  border-radius: 20px;
  font-size: 0.85em;
}

/* 卡片过渡动画 */
.card-enter-active,
.card-leave-active {
  transition: all 0.4s ease;
}

.card-leave-active {
  position: absolute;
}

.card-enter-from {
  opacity: 0;
  transform: scale(0.8) translateY(30px);
}

.card-leave-to {
  opacity: 0;
  transform: scale(0.8) translateY(-30px);
}

.card-move {
  transition: transform 0.4s ease;
}
</style>
